#include "EventLoopThread.h"
#include "EventLoop.h"


EventLoopThread::EventLoopThread(const ThreadInitCallback &cb,
    const std::string &name)
    :loop_(nullptr)
    ,exiting_(false)
    ,thread_(std::bind(&EventLoopThread::threadFunc,this), name)
    ,mutex_()
    ,cond_()
    ,callback_(cb)
{
    
}
EventLoopThread:: ~EventLoopThread()
{
    exiting_ = true;
    if(loop_ != nullptr)
    {
        loop_->quit();
        thread_.join();
    }
}
//mutex_和cond_用于确保主线程能够安全地获取到子线程创建的 EventLoop 对象地址。
EventLoop* EventLoopThread::startLoop()
{
    thread_.start();//启动底层的线程
    EventLoop *loop = nullptr;
    {   // 2. 加锁保护共享数据 loop_
        std::unique_lock<std::mutex> lock(mutex_);
        while ( loop_ == nullptr) // 3. 等待条件：loop_ != nullptr
        {
            cond_.wait(lock);// 4. 等待通知，自动释放锁
        }// 5. 条件满足，wait 返回时已重新获得锁
        loop = loop_;
    } // 6. lock 析构，释放锁
    return loop;// 7. 返回获取到的 EventLoop 指针
}
//下面这个方法是在单独的新线程里面运行的
void EventLoopThread::threadFunc()
{
    EventLoop loop;//1. 创建一个独立的eventloop，和上面的线程是一一对应的，one loop per thread
    if(callback_)
    {
        callback_(&loop);// 2. 可选的初始化回调
    }
    {   // 3. 加锁保护共享数据 loop_
        std::unique_lock<std::mutex> lock(mutex_);
        loop_ = &loop;// 4. 将地址赋给共享变量
        cond_.notify_one();// 5. 通知等待的主线程：「loop_ 已就绪！」
    }// 6. lock 析构，自动释放锁
    loop.loop(); // EventLoop loop => Poller.poll 7. 进入事件循环（阻塞在这里）
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;// 9. 防止悬空指针
}